.TH hal_stream "3hal" "2006-10-12" "LinuxCNC Documentation" "HAL"
.de FU
.sp
.ti -4
\\$*
..
.de FF
.br
.ti -4
\\$*
..
.SH NAME

hal_stream \- non-blocking realtime streams

.SH SYNOPSIS

.FU .B #include <hal.h>
.FU int hal_stream_create(hal_stream_t *stream, int comp_id, int key, int depth, const char *typestring);
.FF void hal_stream_destroy(hal_stream_t *stream);
.FF int hal_stream_attach(hal_stream_t *stream, int comp_id, int key, const char *typestring);
.FF int hal_stream_detach(hal_stream_t *stream);

.FU int hal_stream_element_count(hal_stream_t *stream);
.FF hal_type_t hal_stream_element_type(hal_stream_t *stream, int idx);
.FF int hal_stream_depth(hal_stream_t *stream);
.FF int hal_stream_maxdepth(hal_stream_t *stream);
.FF int hal_stream_num_underruns(hal_stream_t *stream);
.FF int hal_stream_num_overruns(hal_stream_t *stream);

.FU int hal_stream_read(hal_stream_t *stream, union hal_stream_data *buf, unsigned *sampleno);
.FF bool hal_stream_readable(hal_stream_t *stream);

.FU int hal_stream_write(hal_stream_t *stream, union hal_stream_data *buf);
.FF bool hal_stream_writable(hal_stream_t *stream);

.FU .B #ifdef ULAPI
.FF void hal_stream_wait_writable(hal_stream_t *stream, sig_atomic_t *stop);
.FF void hal_stream_wait_readable(hal_stream_t *stream, sig_atomic_t *stop);
.FF .B #endif


.SH DESCRIPTION
A HAL stream provides a limited ability for two components to communicate
data which does not fit within the model of HAL pins.  A reader and a writer
must agree on a
.I key
(32-bit integer identifier) and a data structure
specified by
.I typestring
.  They must also agree which component (the first one loaded)
will
.B hal_stream_create
the stream, and wich component (the second one loaded) will
.B hal_stream_attach
to the already-created stream.

The userspace part can be
.BR halstreamer " or " halsampler .
In the case of
.B halstreamer
the key is 0x48535430 plus the channel number.  In the case of
.B halsampler
the key is 0x48534130 plus the channel number.

.SS \fBhal_stream_create\fR
Create the given stream, initializing the \fIstream\fR which is passed by
reference.  If is an undiagnosed error if a stream has already been created with the same \fIkey\fR.

.SS \fBhal_stream_destroy\fR
Destroy the given stream.  It is an undiagnosed error if the stream is still attached by another component.  It is an undiagnosed error if the stream was attached with
.B hal_stream_attach
rather than created with
.BR hal_stream_create .
It is an undiagnosed error if the call to
.B hal_stream_destroy
is omitted.

.SS \fBhal_stream_attach\fR
Attach the given stream, which was already created by
.BR hal_stream_create .
If the typestring is specified, this call fails if it does not match the
typestring the stream was created with.  If the typestring argument is NULL,
then any typestring is accepted.

.SS \fBhal_stream_detach\fR
Detach the given stream.  It is an undiagnosed error if the stream was created with
.B hal_stream_create
rather than attached with
.BR hal_stream_attach .
It is an undiagnosed error if the call to
.B hal_stream_detach
is omitted.

.SS \fBhal_stream_element_count\fR
Returns the number of pins.

.SS \fBhal_stream_element_type\fR
Returns the type of the given pin number.

.SS \fBhal_stream_readable\fR
Returns true if the stream has at least one sample to read
.SS \fBhal_stream_read\fR
If the stream has one sample to read, stores it in buf.
.SS \fBhal_stream_writable\fR
Returns true if the stream has room for at least one sample to be written.
.SS \fBhal_stream_depth\fR
Returns the number of samples waiting to be read.
.SS \fBhal_stream_maxdepth\fR
Returns the
.B depth
argument that the stream was created with.
.SS \fBhal_stream_num_overruns\fR
Returns a number which is incremented each time
.B hal_stream_write
is called without space available.
.SS \fBhal_stream_num_underruns\fR
Returns a number which is incremented each time
.B hal_stream_read
is called without a sample available.

.SS \fBhal_stream_wait_readable\fR
Waits until the stream is readable or the stop flag is set.

.SS \fBhal_stream_wait_writable\fR
Waits until the stream is writable or the stop flag is set.

.SS \fBhal_stream_read\fR
Reads a record from stream.  If successful, it is stored
in the given buffer.  Optionally, the sample number can be retrieved.
If no sample is available,
.I num_underruns
is incremented.  It is an undetected error if more than one component or
real-time function calls
.B hal_stream_read
concurrently.

.SS \fBhal_stream_write\fR
Writes a record to the stream.  If successful, it copied from the given
buffer.  If no room is available,
.I num_overruns
is incremented.  In either case, the internal
.I sampleno
value is incremented.
  It is an undetected error if more than one component or
real-time function calls
.B hal_stream_write
concurrently.

.SH ARGUMENTS
.IP \fIstream\fR
A pointer to a stream object.  In the case of
.BR hal_stream_create " and " hal_stream_attach
this is an uninitialized stream; in other cases, it must be a stream
created or attached by an earlier call and not yet detached or destroyed.

.IP \fIhal_id\fR
An HAL component identifier returned by an earlier call to \fBhal_init\fR.

.IP \fIkey\fR
The key for the shared memory segment.

.IP \fIdepth\fR
The number of samples that can be unread before any samples are lost (overrun)

.IP \fItypestring\fR
A typestring is a case-insensitive string which consists of one or more of the following type characters:
.RS 4
.IP B
for bool / hal_bit_t
.IP S
for int32_t / hal_s32_t
.IP U
for uint32_t / hal_u32_t
.IP F
for real_t / hal_float_t
.RE
A typestring is limited to 16 characters.
.IP \fIbuf\fR
A buffer big enough to hold all the data in one sample.

.IP \fIsampleno\fR
If non-NULL, the last sample number is stored here.  Gaps in this sequence
indicate that an overrun occured between the previous read and this one.  May
be NULL, in which case the sample number is not retrieved.

.IP \fIstop\fR
A pointer to a value which is monitored while waiting.  If it is nonzero,
the wait operation returns early.  This allows a wait call to be safely
terminated in the case of a signal.

.SH SAMPLE CODE
In the source tree under
.IR src/hal/components ,
.BR sampler.c " and " streamer.c
are realtime components that read and write hal streams.

.SH REALTIME CONSIDERATIONS
.BR hal_stream_read ", " hal_stream_readable ", " hal_stream_write ", " hal_stream_writable ", " hal_stream_element_count ", " hal_tream_pin_type ", " hal_stream_depth ", " hal_stream_maxdepth ", " hal_stream_num_underruns ", " hal_stream_number_overruns
may be called from realtime code.

.BR hal_stream_wait_writable ", " hal_stream_wait_writable
may be called from ULAPI code.

Other functions may be called in any context, including realtime contexts.
.SH RETURN VALUE
.BR hal_stream_create " , " hal_stream_attach " , " hal_stream_read " , " hal_stream_write " , " hal_stream_detach " and " hal_stream_destroy
return an RTAPI status code.  Other functions' return values are explained above.

.SH BUGS
The memory overhead of a stream can be large.  Each element in a record uses 8
bytes, and the implicit sample number also uses 8 bytes.  As a result, a stream
which is used to transport 8-bit values uses 94% of its memory as overhead.
However, for modest stream sizes this overhead is not important.  (this memory
is part of its own shared memory region and does not count against the
HAL shared memory region used for pins, parameters and signals)

.SH SEE ALSO
.BR sampler (9),
.BR streamer (9),
.BR halsampler (1),
.BR halstreamer (1)
